/**
 * 定义ts类
 */
class Point {
    public readonly color: string = "red" // 公共只读属性
    public x: number // 默认public
    protected y: number // 受保护的属性
    private z: number = 0 // 私有属性并赋初值
    constructor(x: number, y: number) {
        this.x = x
        this.y = y
    }
    public getPosition() {
        return this.x + "-" + this.y
    }
}

const point = new Point(1, 2)

/**
 * 类的继承
 */
class Parent {
    public age: number
    // protected constructor(age: number) { // 如果构造函数添加protected 不能创建实例只能被子类继承
    //constructor(public age: number) { // 带修饰符（这里为public）的参数会自动添加到类中并赋值
    constructor(age: number) {
        this.age = age
    }
    getAge() {
        return this.age
    }
}
class Child extends Parent {
    constructor(age: number) {
        super(age)
    }
    getAge2() {
        console.log(Child.sex);// 类内访问静态属性
        return super.getAge()
    }
    public static sex = "man"

    //set get 略，与ES6一致
}
const Childname = new Child(1)
console.log(Childname.getAge())
console.log(Childname.getAge2());
console.log(Child.sex); // 访问静态属性

// 抽象类 略，与其它语言类似，抽象类关键字 abstract ，abstract还用于定义抽象方法 和属性
// 接口与接口实现  //与其它语言类似 略  关键字: 接口(interface), 接口实现(implements)
// 接口可以继承类
class A {
    public Aname: string = "aname"
}
interface I extends A { }
class B extends A implements I {
    public Bname: string = "bname"
}
console.log((new B).Aname);
console.log((new B).Bname);

/**
 * 再泛型中使用类类型
 */

// 工厂函数 new()这里表示的是调用类(c)的构造函数,返回实例的类型为T
// const create = <T>(c: new () => T): T => {
const create = <T>(c: { new(): T }): T => {
    return new c()
}
class Infos {
    public age: number = 18
}
console.log(create(Infos))
console.log(create<Infos>(Infos))